Skip to content

Conversation

@stackotter
Copy link
Collaborator

@stackotter stackotter commented Jun 26, 2025

This PR introduces various APIs related to improving interoperability between SwiftCrossUI view code and native UI frameworks. This includes:

  • Making it easier to make platform-specific modifications to the native widgets behind SwiftCrossUI views via the inspect family of modifiers
    • This allows people to work around missing SwiftCrossUI features and to access niche platform-specific APIs that we don't plan on wrapping
  • Enabling the hosting of native views in SwiftCrossUI apps via the FooRepresentable family of types
    • (SwiftCrossUI already NSViewRepresentable, UIViewRepresentable and UIViewControllerRepresentable, but we still need to introduce similar APIs for the non-Apple backends)

I've introduced an AdvancedCustomizationExample app to showcase these new advanced customisation APIs.

Future directions

  • Enable the hosting of SwiftCrossUI views in native apps via a FooHostingView family of types

@stackotter stackotter force-pushed the backend_interop branch 4 times, most recently from 2407a98 to 2797197 Compare June 26, 2025 07:46
@stackotter
Copy link
Collaborator Author

I've created the FooRepresentable family of protocols now. Next I'll working on the FooHostingView family of views and then I'll come back and try to improve the experience of using the FooRepresentable protocols. The naming of the protocol requirements currently differ in just enough ways to be annoying when copy and pasting an existing implementation to adapt it for a new backend. Some suggestions were given in the Discord server that I'm considering going with.

The hardest part of implementing the FooRepresentable family of protocols was integrating with the layout system of the underlying native frameworks. Each framework exposes a different measurement API with unique limitations. The WinUI one is probably the most fragile because I had to apply a similar hack to the one used to get natural sizing working correctly; any WinUI elements that SwiftCrossUI itself doesn't already use are likely to have incorrect sizes before the first render. The other dodgy implementation is the GtkBackend one. It seems to work well enough, but throws a bunch of warnings because we occasionally measure with less height/width than the underlying widget can work with. I've searched around for APIs that would tell us what these minimum workable dimensions are, but I haven't found any yet. The issue is that when measuring you provide one dimension and get minimum/natural dimensions for the other dimension, but Gtk never actually tells you how much of the provided dimension it wants to use. Gtk 3 doesn't seem to care.

@stackotter stackotter force-pushed the backend_interop branch 3 times, most recently from 288ce91 to a02da75 Compare July 10, 2025 04:05
@stackotter
Copy link
Collaborator Author

I've rebased this PR onto main now, which required a lot of tweaking within the ...Representable family of protocols, particularly in regards to their default sizeThatFits implementations.

I'm going to leave the ...HostingView family of structs for a future pull request in the interest of getting the existing improvements merged and moving on to other important work.

@stackotter stackotter marked this pull request as ready for review January 9, 2026 03:01
@stackotter stackotter force-pushed the backend_interop branch 3 times, most recently from 60f85c3 to ec05cd0 Compare January 9, 2026 05:36
These changes make platform-specific native customizations significantly
easier to perform. Hopefully this will make SwiftCrossUI significantly
more viable for actual production apps that often just need to get
things working even if there's not a nice neat first party API for it
yet.

Inspiration was taken from swiftui-introspect.
The Swift Package Collection signing certificate used by Xcode 15.4
expired 10 hours ago and broke any workflows that used xcodebuild (for
SwiftCrossUI's CI at least). It's probably a good that that all
platforms are getting tested against the same Swift version now anyway.
@stackotter stackotter merged commit 6d3d506 into main Jan 9, 2026
22 checks passed
@stackotter stackotter deleted the backend_interop branch January 9, 2026 07:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants